<style lang="scss" scoped>
.flex-end {
    display: flex;
    align-items: center;
    justify-content: flex-end;
}
</style>

<template>
    <div class="app-container">
        <el-card class="card">
            <el-form :model="queryParams" inline>
                <el-form-item label="关键字">
                    <el-input v-model="queryParams.name" placeholder="请输入菜单名称"></el-input>
                </el-form-item>
                <el-form-item label-width="15px">
                    <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>
                    <el-button type="info" icon="el-icon-refresh-right" @click="handleRefresh">刷新</el-button>
                </el-form-item>
            </el-form>
        </el-card>
        <el-card class="table">
            <div class="table-buttons">
                <el-button v-waves type="primary" icon="el-icon-plus" @click="handleShowAlert(true)">添加</el-button>
            </div>
            <el-table v-loading="loading" :data="list" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" row-key="id">
                <el-table-column label="菜单名称" v-slot="{ row }" show-overflow-tooltip>
                    <svg-icon :icon-class="row.icon" v-if="row.icon" class-name="disabled" /> {{ row.name }}
                </el-table-column>
                <el-table-column align="center" prop="type" label="类型" v-slot="{ row }">
                    <el-tag v-if="row.type == 1" type="warning">目录</el-tag>
                    <el-tag v-else-if="row.type == 2" type="success">菜单</el-tag>
                    <el-tag v-else-if="row.type == 3" type="danger">按钮</el-tag>
                    <el-tag v-else-if="row.type == 4" type="info">外链</el-tag>
                    <el-tag v-else>error</el-tag>
                </el-table-column>
                <el-table-column prop="path" label="路由名称" v-slot="{ row }" show-overflow-tooltip>
                    <template>{{ row.route_name || '无' }}</template>
                </el-table-column>
                <el-table-column prop="path" label="路由路径" v-slot="{ row }" show-overflow-tooltip>
                    <template>{{ row.path || '无' }}</template>
                </el-table-column>
                <el-table-column label="组件路径" v-slot="{ row }" show-overflow-tooltip>
                    <template>{{ row.component || 'Layout' }}</template>
                </el-table-column>
                <el-table-column label="权限标识" v-slot="{ row }" show-overflow-tooltip>
                    {{ row.perm || '无' }}
                </el-table-column>
                <el-table-column align="center" label="状态" v-slot="{ row }">
                    <el-tag v-if="row.hidden == 0" type="success">显示</el-tag>
                    <el-tag v-else-if="row.hidden == 1" type="danger">隐藏</el-tag>
                </el-table-column>
                <el-table-column align="center" prop="sort" label="排序" />
                <el-table-column align="center" v-slot="{ row }" label="操作" width="200px" fixed="right">
                    <el-button type="text" icon="el-icon-plus" size="small" @click="hanldeShowAlertItemAdd(row)">添加</el-button>
                    <el-button type="text" icon="el-icon-edit" size="small" @click="handleShowAlert(false, row)">编辑</el-button>
                    <el-button type="text" icon="el-icon-delete" size="small" @click="submitRemove(row)">删除</el-button>
                </el-table-column>
            </el-table>
        </el-card>
        <el-dialog :title="isAdd ? '新增菜单' : '编辑菜单'" :visible.sync="dialogVisible" top="5vh" width="1000px" :before-close="closeClearFormData" destroy-on-close>
            <el-form :model="formData" label-width="160px" size="small" ref="ruleForm">
                <el-form-item label="父级菜单" required>
                    <el-cascader v-model="formData.parent_id" :options="options" :props="{ checkStrictly: true, value: 'id', label: 'name' }"></el-cascader>
                </el-form-item>
                <el-form-item label="菜单名称" required>
                    <el-input type="text" placeholder="请输入菜单名称" v-model="formData.name"></el-input>
                </el-form-item>
                <el-form-item label="菜单类型" required>
                    <el-radio-group v-model="formData.type">
                        <el-radio :label="1">目录</el-radio>
                        <el-radio :label="2">菜单</el-radio>
                        <el-radio :label="3">按钮</el-radio>
                        <el-radio :label="4">外链</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="路由名称" v-if="formData.type == 1 || formData.type == 2" required>
                    <el-input type="text" placeholder="System" v-model="formData.route_name" v-if="formData.type == 1"></el-input>
                    <el-input type="text" placeholder="User" v-model="formData.route_name" v-if="formData.type == 2"></el-input>
                </el-form-item>
                <el-form-item label="路由路径" v-if="formData.type == 1 || formData.type == 2" required>
                    <el-input type="text" placeholder="system" v-model="formData.path" v-if="formData.type == 1"></el-input>
                    <el-input type="text" placeholder="user" v-model="formData.path" v-if="formData.type == 2"></el-input>
                </el-form-item>
                <el-form-item label="页面路径" v-if="formData.type == 2" required>
                    <el-input v-model="formData.component" placeholder="system/user/index">
                        <template #prepend v-if="formData.type == 2">src/views/</template>
                        <template #append v-if="formData.type == 2">.vue</template>
                    </el-input>
                </el-form-item>
                <el-form-item label="外链地址" v-if="formData.type == 4" required>
                    <el-input v-model="formData.path" placeholder="请输入外链完整地址"></el-input>
                </el-form-item>
                <el-form-item label="显示状态" v-if="formData.type != 3" required>
                    <el-radio-group v-model="formData.hidden">
                        <el-radio :label="0">显示</el-radio>
                        <el-radio :label="1">隐藏</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="是否缓存" v-if="formData.type == 2">
                    <el-radio-group v-model="formData.no_cache">
                        <el-radio :label="0">是</el-radio>
                        <el-radio :label="1">否</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item v-if="formData.type == 1">
                    <template #label>
                        <div class="flex-end">
                            根目录始终显示
                            <el-tooltip effect="light">
                                <template #content>
                                    是：根目录只有一个子路由显示目录
                                    <br />否：根目录只有一个子路由不显示目录，只显示子路由
                                </template>
                                <i class="el-icon-question"></i>
                            </el-tooltip>
                        </div>
                    </template>
                    <el-radio-group v-model="formData.always_show">
                        <el-radio :label="1">是</el-radio>
                        <el-radio :label="0">否</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="排序">
                    <el-input-number v-model="formData.sort" :min="0" placeholder="请选则排序" controls-position="right" />
                </el-form-item>
                <el-form-item label="图标" v-if="formData.type != 3">
                    <icon-select v-model="formData.icon" placeholder="点击选择图标"></icon-select>
                </el-form-item>
                <!--  label="跳转路由" -->
                <el-form-item v-if="formData.type == 1 || formData.type == 2">
                    <template #label>
                        <div class="flex-end">
                            跳转路由
                            <el-tooltip effect="light">
                                <template #content>
                                    如果输入了 noRedirect，则不会在 breadcrumb 中重定向
                                </template>
                                <i class="el-icon-question"></i>
                            </el-tooltip>
                        </div>
                    </template>
                    <el-input v-model="formData.redirect" placeholder="noRedirect" />
                </el-form-item>
                <el-form-item label="权限标识" v-if="formData.type == 3">
                    <el-input v-model="formData.perm" placeholder="请输入权限标识" />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="closeClearFormData">取 消</el-button>
                <el-button type="primary" @click="isAdd ? submitAdd() : submitEdit()">确 定</el-button>
            </template>
        </el-dialog>
    </div>
</template> 

<script>
import '@/assets/css/clear-card.css'
import waves from '@/directive/waves/index.js' // 水波纹指令
import IconSelect from '@/components/IconSelect'
import { add, getOptions, getList, edit, remove } from '@/api/system/menu.js'
export default {
    name: 'Menu',
    components: { IconSelect },
    directives: { waves },
    data() {
        return {
            // 查询参数
            queryParams: {},
            // 菜单列表数据
            list: [],
            // 菜单列表条数
            total: 0,
            // 数据加载中控件
            loading: true,
            // 当前弹出窗口是添加或者修改，true：添加；false：修改
            isAdd: true,
            // 表单控件
            dialogVisible: false,
            // 新增 | 编辑，数据表单
            formData: {
                // 父菜单 id
                parent_id: 0,
                // 菜单名称
                name: undefined,
                // icon 图标
                icon: undefined,
                // 类型：1-目录，2-菜单，3-按钮权限，4-外链
                type: 2,
                // 路由名称
                route_name: undefined,
                // 路由地址
                path: undefined,
                // 组件路径(vue页面完整路径，省略.vue后缀)
                component: undefined,
                // 权限标识
                perm: undefined,
                // 排序（数字越小排名越靠前）
                sort: 1,
                // 跳转路径
                redirect: undefined,
                // 是否隐藏该路由：1-隐藏，0-显示
                hidden: 0,
                // 如果设置为 1，将始终显示根菜单;如果没有设置 alwaysShow，当 item 有多于一个子路由时，它将变成嵌套模式，否则不显示根菜单
                always_show: 0,
                // 如果设置为 1，页面将不会被缓存(默认为 0)
                no_cache: undefined
            },
            // 父菜单列表下拉框
            options: [],
            // 添加修改接口节流阀门
            throttle: true,
        }
    },
    created() {
        this.getList()
    },
    watch: {
        dialogVisible(value) {
            if (value) {
                this.getOptions()
            }
        }
    },
    methods: {
        hanldeShowAlertItemAdd(row) {
            this.$set(this.formData, 'parent_id', row.id)
            // 弹出弹窗层
            this.dialogVisible = true
            // 设置弹窗类型。true：添加；false：修改；
            this.isAdd = true
        },
        submitRemove(row) {
            const { id } = row
            this.$confirm('将会删除当前菜单和子类菜单，请谨慎操作', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
            }).then(() => {
                return remove(id)
            }).then(({ message }) => {
                this.$message.success(message)
                this.getList()
            }).catch(() => {
                this.$message.info('已取消')
            })
        },
        submitEdit() {
            const form = { ...this.formData }
            if (typeof form.parent_id == 'object') {
                form.parent_id = form.parent_id.at(-1)
            }
            if (form.parent_id == 'super') {
                form.parent_id = 0
            }
            if (!form.component) {
                form.component = 'Layout'
            }
            if (this.throttle) {
                this.throttle = false
                edit(form).then(({ message }) => {
                    this.$message.success(message)
                    this.getList()
                    this.closeClearFormData()
                }).finally(() => {
                    this.throttle = true
                })
            }
        },
        submitAdd() {
            const form = { ...this.formData }
            if (typeof form.parent_id == 'object') {
                form.parent_id = form.parent_id.at(-1)
            }
            if (form.parent_id == 'super') {
                form.parent_id = 0
            }
            if (!form.component) {
                form.component = 'Layout'
            }
            if (this.throttle) {
                this.throttle = false
                add(form).then(({ message }) => {
                    this.$message.success(message)
                    this.getList()
                    this.closeClearFormData()
                }).finally(() => {
                    this.throttle = true
                })
            }
        },
        handleShowAlert(alertTypeBool, row) {
            // 弹出弹窗层
            this.dialogVisible = true
            // 设置弹窗类型。true：添加；false：修改；
            this.isAdd = alertTypeBool
            // 如果为修改弹窗，回显字段值并渲染页面
            if (!this.isAdd) {
                if (row.parent_id == 0) {
                    this.$set(this.formData, 'parent_id', 'super')
                } else {
                    this.$set(this.formData, 'parent_id', row.parent_id)
                }
                this.$set(this.formData, 'id', row.id)
                this.$set(this.formData, 'name', row.name)
                this.$set(this.formData, 'icon', row.icon)
                this.$set(this.formData, 'type', row.type)
                this.$set(this.formData, 'route_name', row.route_name)
                this.$set(this.formData, 'path', row.path)
                this.$set(this.formData, 'component', row.component)
                this.$set(this.formData, 'perm', row.perm)
                this.$set(this.formData, 'sort', row.sort)
                this.$set(this.formData, 'redirect', row.redirect )
                this.$set(this.formData, 'hidden', row.hidden)
                this.$set(this.formData, 'always_show', row.always_show)
                this.$set(this.formData, 'no_cache', row.no_cache)
            }
        },
        // 监听搜索按钮点击事件
        handleSearch() {
            this.getList()
        },
        // 监听刷新按钮点击事件
        handleRefresh() {
            this.$data.queryParams = this.$options.data().queryParams
            this.getList()
        },
        handleChangeStatus() { },
        // 关闭弹窗时，需要清楚所有的form表单的数据
        closeClearFormData() {
            this.$data.formData = this.$options.data().formData
            this.dialogVisible = false
        },
        // 获取父级菜单 id
        async getOptions() {
            const { data } = await getOptions()
            this.options = data
        },
        // 获取列表信息
        async getList() {
            this.loading = true
            const query = { ...this.queryParams }
            const { data } = await getList(query)
            this.list = data
            this.loading = false
        }
    }
}
</script>
